/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.*;
import java.io.*;
import javax.persistence.*;

/**
 *
 * @author Carlos
 */
@Entity
public class Usuario implements Serializable{
    @Id
    private String email;
    private String clave;
    private String nombre;
    private String descripcion;
    private FichaAcademica notas;
    
    
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="user_mensaj",
    joinColumns=@JoinColumn(name="email"),
    inverseJoinColumns=@JoinColumn(name="idMensaje")
    )
    private List<Mensaje> mensajes; 
    
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="user_privados",
    joinColumns=@JoinColumn(name="email"),
    inverseJoinColumns=@JoinColumn(name="idMensaje")
    )
    private List<MensajePrivado> privados;
    
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="tbl_amigos",
    joinColumns=@JoinColumn(name="email"),
    inverseJoinColumns=@JoinColumn(name="amigoEmail")
    )
    private List<Usuario> amigos;
    
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="tbl_solicitudes",
    joinColumns=@JoinColumn(name="email"),
    inverseJoinColumns=@JoinColumn(name="amigoEmail")
    )
    private List<Usuario> solicitudes;

       
    public Usuario(String aemail, String aclave, String anombre, String adescripcion){
        email=aemail;
        clave=aclave;
        nombre=anombre;
        descripcion=adescripcion;
        solicitudes= new ArrayList();
        mensajes=new ArrayList();
        amigos=new ArrayList();
        privados=new ArrayList();
        notas=new FichaAcademica();
        
}//Constructor con parámetros
    public Usuario(){
        email="";
        clave="";
        nombre="";
        descripcion="";
        solicitudes= new ArrayList();
        mensajes=new ArrayList();
        amigos=new ArrayList();
        privados=new ArrayList();
        notas=new FichaAcademica();
    }//Constructor por defecto; Todo en blanco
    
    boolean clavevalida(String aclave){
        return clave.equals(aclave);
    }//Devuelve si la clave coincide con la guardada
    
    public void mensajeMuro(String msg){
        Mensaje m;
        Date fecha;
        Usuario user;//para mandar el mensajes a mis amigos
        fecha=new Date();
        m= new Mensaje(nombre,fecha,msg);
        mensajes.add(m);
        try{
            DAOUser.instancia().actualizar(this);
        }catch(Exception e){
            return;
        }
        Iterator iterador = amigos.listIterator();
        while( iterador.hasNext() ) {
           user= (Usuario) iterador.next();
           user.mensajes.add(m);
           try{
                DAOUser.instancia().actualizar(user);
            }catch(Exception e){
                return;
            }
        }  
    }//Manda el mensaje a mi muro y al de mis amigos
    
    public void mensajeAmigo(String msg, Usuario aemisor)throws Exception {
        Exception e=new Exception();
        
               if(esAmigo(aemisor)){
                    MensajePrivado m;
                    Date fecha=new Date();
                    m=new MensajePrivado(aemisor.leeNombre(),fecha,msg,this);
                    privados.add(m);
                    try{
                        DAOUser.instancia().actualizar(this);
                    }catch(Exception ex){
                        throw ex;
            }
               }else{
                    throw e;
               }    
    }//Recibo un privado
    
    public void admitirAmigo(Usuario u)throws  Exception{
        
         Exception e=new Exception();
         //Primero compruebo si tengo una petición del usuario
        if (!compruebaPeticion(u)){
            throw e;
        }
        //Ahora quito la peticion de amistad de la lista de pendientes
        solicitudes.remove(u);
        amigos.add(u);//Añado el amigo a mi lista    
        u.amigos.add(this);
        try{
                DAOUser.instancia().actualizar(this);
            }catch(Exception ex){
                throw ex;
            }
        try{
                DAOUser.instancia().actualizar(u);
            }catch(Exception ex){
                throw ex;
            }
        
    }//Añado un amigo a la lista
        
    public void solicitudAmistad(Usuario u) throws Exception{
        
        
        Exception e=new Exception();
        //Primero compruebo si le he mandado una petición antes
        if (compruebaPeticion(u)){
            throw e;
        }
        //Segundo compruebo si yo ya estoy en la lista de peticiones del otro user
          
        if(u.compruebaSolicitud(this)){
            throw e;
        }
        //Ahora compruebo si ya somos amigos
        if(esAmigo(u)){
                throw e;
        }
        if(u.leeEmail().equals(this.leeEmail())){
               throw e;
        }
        solicitudes.add(u);
        try{
                DAOUser.instancia().actualizar(this);
            }catch(Exception ex){
                throw ex;
            }
        
    }//Mandar una solicitud de amistad a un usuario
    
    boolean compruebaPeticion(Usuario u){
        Usuario temp;
        Iterator itera=solicitudes.listIterator();
        while(itera.hasNext()){
            temp=(Usuario) itera.next();
            if (temp.leeEmail()==u.leeEmail()) 
                return true;
        }   
        return false;
    }//Comprueba si u está ya en mi lista de peticiones 
    
    public String leeNombre(){  
        return nombre;
    }   
    
    public String leeEmail(){
        return email;
    }
    public Collection leeMensajesUsuario(){
        
        Mensaje men;
        Collection <Mensaje> m;
        m = new ArrayList<Mensaje>();  
        //Buscamos los mensajes del user
        Iterator itera = mensajes.listIterator();
      		while(itera.hasNext()){
                men=(Mensaje) itera.next();
                m.add(men);
                }
         return m;
    }//Devuelvo una collecion con todos los mensajes de mi muro
    
    public FichaAcademica leeNotas(){
        return notas;
    }
    public Collection leeMensajesPrivados(){
        
        Mensaje men;
        Collection <Mensaje> m;
        m = new ArrayList<Mensaje>();  
        //Buscamos los mensajes del user
        Iterator itera = privados.listIterator();
      		while(itera.hasNext()){
                men=(Mensaje) itera.next();
                m.add(men);
                }
         return m;
    } //Devuelve una colección con los mensajes privados del usuario
  
    boolean compruebaSolicitud(Usuario u){
        Usuario temp;
       Iterator itera=solicitudes.listIterator();
        while(itera.hasNext()){
           temp=(Usuario) itera.next();
            if (temp==u) {
           
               return true;
            }
        }
        return false;
    }//Compruebo si un usuario está en mi lista de solicitudes
    
    public Collection verAmigos(){
        
        Usuario u;
        Collection <Usuario> a;
        a = new ArrayList<Usuario>();  
        //Buscamos los amigos del usuario
        Iterator itera = amigos.listIterator();
      		while(itera.hasNext()){
                u=(Usuario) itera.next();
                a.add(u);
                }
         return a;
    }//Devuelvo una collecion con todos mis amigos
    
    public Collection verSolicitudes(){
        
        Usuario u;
        Collection <Usuario> a;
        a = new ArrayList<Usuario>();  
        //Buscamos los amigos del usuario
        Iterator itera = solicitudes.listIterator();
      		while(itera.hasNext()){
                u=(Usuario) itera.next();
                a.add(u);
                }
         return a;
    }//Devuelvo una collecion con las solicitudes de amistad
    
    boolean esAmigo(Usuario u){
        Usuario temp;
        Iterator itera=amigos.listIterator();
        while(itera.hasNext()){
            temp=(Usuario) itera.next();
            if(temp.leeEmail().equals(u.leeEmail())){
                return true;
        }}
        return false;
    } //Comprueba si un usuario es nuestro amigo
    
    
    
    public String leeDescripcion(){
       return descripcion;
    }
    public String leeclave(){
        return clave;
    }
    public String numsolicitudes(){
        String num="0";
        num= Integer.toString(solicitudes.size());
        return num;
    }//Devuelve el numero de solicitudes que tenemos pendientes
}
